﻿using System.Reflection;
using System.Text;

namespace Dunet.Generator.UnionGeneration;

internal static class StringBuilderExtensions
{
    public static StringBuilder AppendTypeParams(
        this StringBuilder builder,
        IReadOnlyList<TypeParameter> typeParams
    )
    {
        if (typeParams.Count <= 0)
        {
            return builder;
        }

        var typeParamsCsv = string.Join(
            ", ",
            typeParams.Select(static typeParam => typeParam.Identifier)
        );

        return builder.Append("<").Append(typeParamsCsv).Append(">");
    }

    /// <summary>
    /// Appends name of the given union, including each of its parent types separated by dots.
    /// </summary>
    /// <param name="builder">The string builder to append to.</param>
    /// <param name="union">The union to append the full name of.</param>
    public static StringBuilder AppendFullUnionName(
        this StringBuilder builder,
        UnionDeclaration union
    )
    {
        var parentTypes = string.Join(".", union.ParentTypes);
        builder.Append(parentTypes);

        if (union.ParentTypes.Count > 0)
        {
            builder.Append(".");
        }

        return builder.Append(union.Name);
    }

    public static StringBuilder AppendAutoGeneratedCommentLine(this StringBuilder builder) =>
        builder.AppendLine("// <auto-generated/>");

    /// <summary>
    /// Appends the GeneratedCodeAttribute, to better enable the code to be detected as generated.
    /// </summary>
    /// <param name="builder">The string builder to append to.</param>
    public static StringBuilder AppendGeneratedCodeAttributeLine(this StringBuilder builder) =>
        builder.AppendLine(
            $$"""[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Dunet.Generator", "{{GeneratorVersion}}")]"""
        );

    public static StringBuilder AppendPragmaWarningDisableCs1591Line(this StringBuilder builder) =>
        builder
            .AppendLine("// Disable CS1591 - Missing XML comment on public member")
            .AppendLine("#pragma warning disable 1591");

    public static StringBuilder AppendPragmaWarningRestoreCs1591Line(this StringBuilder builder) =>
        builder
            .AppendLine("// Disable CS1591 - Missing XML comment on public member")
            .AppendLine("#pragma warning restore 1591");

    private static string? GeneratorVersion { get; } = GetGeneratorVersion();

    private static string? GetGeneratorVersion()
    {
        var assembly = typeof(UnionGenerator).Assembly;
        var attribute = assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>();
        return attribute?.InformationalVersion;
    }
}
